在 Windows Forms 應用程式中加入「載入動畫」並不簡單:解決「UI 執行緒阻塞」問題。
以下是說明、實作步驟及範例程式碼。
當一個表單(Form)取得操作焦點時,其他在背景運行的表單將暫停動作。
因此,當載入動畫出現時,必須另開執行緒在背景中執行接著要顯示的新表單,才能讓動畫持續播放。
這時又產生了一個問題...
由於新表單是透過另一個執行緒開啟的,當新表單顯示時,該執行緒會取得控制權成為主執行緒,
而負責動畫的執行緒則失去控制權,使得關閉動畫的操作無法順利執行。
因此,必須將「關閉動畫」的指令交由處理新表單的執行緒來執行。
藉由使用 async / await 關鍵字,能用最少的程式碼完成以上流程。
private async void btnOpenForm2_Click(object sender, EventArgs e)
{
    using (var formLoading = new FormLoading())
    {
        // 在背景執行緒初始化 Form2,完成後關閉動畫再顯示 Form2
        var loadForm2Task = Task.Run(() =>
        {
            var form2 = new Form2();
            formLoading.DialogResult = DialogResult.OK;
            form2.ShowDialog();
        });
        // 以Dialog顯示loading form,鎖住其他的表單強迫使用者等待
        formLoading.ShowDialog();
        // 等待 Form2 完成初始化並顯示
        await loadForm2Task;
    }
}
public Form2()
{
    InitializeComponent();
    LoadData();
}
private void LoadData()
{
    // 模擬載入時間 (非同步等待 5 秒)
    Thread.Sleep(5000);
    Label lbl = new Label { Text = "loading complete", AutoSize = true };
    this.Controls.Add(lbl);
}
public FormLoading()
{
    InitializeComponent();
    this.StartPosition = FormStartPosition.CenterParent;
    this.FormBorderStyle = FormBorderStyle.None;
}
本文同步發表至我的Blog